package com.eliza.base.views.learn.animation

import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.EnterExitState
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp

object AnimationModifierX {
    @Composable
    fun Show() {
        var swi by remember {
            mutableIntStateOf(0)
        }
        Column {
            Button(onClick = { swi = (swi + 1) % 2 }) {
                Text(text = "ShapesAnimationX ${swi}")
            }
            when (swi) {
                0 -> AnimatedVisibilityX()
                1 -> AnimatedContentX()
            }
        }
    }

    @Composable
    private fun AnimationModifiers() {
        AnimatedVisibilityX()
        AnimatedContentX()
    }

    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    private fun AnimatedVisibilityX() {
        var visible by remember {
            mutableStateOf(true)
        }
        val density = LocalDensity.current
        AnimatedVisibility(
            visible = visible,
//        enter= EnterTransition.None 不应用任何动画,
            enter = slideInVertically {
                // Slide in from 40 dp from the top.
                with(density) { -40.dp.roundToPx() }
            } + expandVertically(
                // Expand from the top.
                expandFrom = Alignment.Top
            ) + fadeIn(
                // Fade in with the initial alpha of 0.3f.
                initialAlpha = 0.3f
            ) + scaleIn(initialScale = 0.3f),
            exit = slideOutVertically() + shrinkVertically() + fadeOut() + scaleOut(targetScale = 0.3f),

            ) {
//        自定义动画
            val background by transition.animateColor(label = "color") { state ->
                if (state == EnterExitState.Visible) Color.Blue else Color.Gray
            }
            Text(
                "AnimatedVisibility 可见性",
                Modifier
                    .fillMaxWidth()
                    .height(200.dp),
                color = background
            )
            // Fade in/out the background and the foreground.
            Box(
                Modifier
                    .fillMaxSize()
                    .background(Color.DarkGray)
            ) {
                Box(
                    Modifier
                        .align(Alignment.Center)
                        .animateEnterExit(
                            // Slide in/out the inner box.
                            enter = slideInVertically(),
                            exit = slideOutVertically()
                        )
                        .sizeIn(minWidth = 256.dp, minHeight = 64.dp)
                        .background(Color.Red)
                ) {
                    Text(text = "为子项添加进入和退出动画效果")
                }
            }
        }
    }

    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    private fun AnimatedContentX() {
        Column {
            Row {
                var count by remember { mutableIntStateOf(0) }
                Button(onClick = { count++ }) {
                    Text("Add")
                }
                //您应始终使用 lambda 参数并将其反映到内容中。API 会将此值用作键，以标识当前显示的内容。
                AnimatedContent(targetState = count, label = "AnimatedContent",
                    transitionSpec = {
                        //可以为 transitionSpec 参数指定 ContentTransform 对象，以自定义此动画行为。
                        //可以使用 with infix 函数来组合 EnterTransition 与 ExitTransition，以创建 ContentTransform。
                        // 将 SizeTransform 应用于 ContentTransform，方法是为前者附加 using infix 函数。
                        // Compare the incoming number with the previous number.
                        if (targetState > initialState) {
                            // If the target number is larger, it slides up and fades in
                            // while the initial (smaller) number slides up and fades out.
                            (slideInVertically { height -> height } + fadeIn())
                                .togetherWith(slideOutVertically { height -> -height } + fadeOut())
                        } else {
                            // If the target number is smaller, it slides down and fades in
                            // while the initial number slides down and fades out.
                            (slideInVertically { height -> -height } + fadeIn())
                                .togetherWith(slideOutVertically { height -> height } + fadeOut())
                        }.using(
                            // Disable clipping since the faded slide-in/out should
                            // be displayed out of bounds.
                            SizeTransform(clip = false)
                        )
                    }
                ) { targetCount ->
                    // Make sure to use `targetCount`, not `count`.
                    Text(text = "AnimatedContent 根据目标状态添加动画效果:Count: $targetCount")
                }
            }
            var expanded by remember { mutableStateOf(false) }
            Surface(
                color = MaterialTheme.colorScheme.primary,
                onClick = { expanded = !expanded }
            ) {
                AnimatedContent(

                    targetState = expanded,
                    transitionSpec = {
                        fadeIn(animationSpec = tween(150, 150)) togetherWith
                                fadeOut(animationSpec = tween(150)) using
                                SizeTransform { initialSize, targetSize ->
                                    if (targetState) {
                                        keyframes {
                                            // Expand horizontally first.
                                            IntSize(targetSize.width, initialSize.height) at 150
                                            durationMillis = 300
                                        }
                                    } else {
                                        keyframes {
                                            // Shrink vertically first.
                                            IntSize(initialSize.width, targetSize.height) at 150
                                            durationMillis = 300
                                        }
                                    }
                                }
                    },
                    label = "",
                ) { targetExpanded ->
                    Text(text = "AnimatedContent")
                    if (targetExpanded) {
                        Text(
                            text = "targetExpanded:子项使用 animateEnterExit",
                            modifier = Modifier
                                .align(Alignment.CenterHorizontally)
                                // 子项使用
                                .animateEnterExit(
                                    // Slide in/out the inner box.
                                    enter = slideInVertically(),
                                    exit = slideOutVertically()
                                )
                        )
                    } else {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
                    }
                }
            }
        }

    }

    @Composable
    private fun AnimatedCrossfadeX() {
        Column {
            var currentPage by remember { mutableStateOf("A") }
            Crossfade(targetState = currentPage, label = "Crossfade") { screen ->
                when (screen) {
                    "A" -> Text("Page A")
                    "B" -> Text("Page B")
                }
            }
        }
    }
}
